<?php
namespace Com\Fetch;

class FDom{
    private $doc = '';

    public function __construct(){
        $this->doc = new \DOMDocument('1.0','UTF-8');
    }

    /**
     *
     *
     * @param $content
     * @param $id
     * @param string $opt value | element
     * @return bool|string
     */
    public function id($content,$id,$opt="value"){
        @$this->doc->loadHTML($content);

        if($opt === "value"){
            return $this->doc->getElementById($id)->textContent;
        }elseif($opt === 'element'){
            $query_string = "//*[@id='$id']";
            return $this->doc->saveHTML((new \DOMXPath($this->doc))->query($query_string)->item(0));
        }else{
            return false;
        }
    }

    /**
     *
     * query by  class
     *
     * @param $content
     * @param $class
     * @param string $opt  value | element
     * @return string
     */
    public function clas($content,$class,$opt="value"){
        @$this->doc->loadHTML($content);

        $query_string = "//*[@class='$class']";
        $result = array();
        if($opt === 'value'){
            foreach ((new \DOMXPath($this->doc))->query($query_string) as $item){
                $result[] = $item->textContent;
            }
        }elseif ($opt === 'element'){
            foreach ((new \DOMXPath($this->doc))->query($query_string) as $item) {
                $result[] = $this->doc->saveHTML($item);
            }
        }else{
            return false;
        }
        return $result;
    }

    /**
     * 取页面匹配到的第一个标签
     *
     * @param $content
     * @param $ele
     * @param $opt  value | element
     * @return bool|string
     */
    public function ele($content,$ele,$opt){
        @$this->doc->loadHTML($content);

        $result = array();
        if($opt === "value"){
            foreach ($this->doc->getElementsByTagName($ele) as $item){
                $result[] = $item->textContent;
            }
        }elseif($opt === 'element'){
            $query_string = "//$ele";
            foreach ((new \DOMXPath($this->doc))->query($query_string) as $item){
                $result[] = $this->doc->saveHTML($item);
            }
        }else{
            return false;
        }

        return $result;
    }

    /**
     * 查询属性
     *
     * @param $content
     * @param $str
     * @param $attr
     * @return array
     */
    public function query_attr($content,$str,$attr){
        @$this->doc->loadHTML($content);

        $query_string = $this->build_query($str);

        $result = array();

        foreach ((new \DOMXPath($this->doc))->query($query_string) as $item){
            $result[] = $item->getAttribute($attr);
        }

        return $result;
    }

    /**
     * 组合抓取
     * @param $content
     * @param $str
     * @param string $opt
     * @return array|bool
     */
    public function query($content,$str,$opt='value'){
        @$this->doc->loadHTML($content);

        $query_string = $this->build_query($str);

        $result = array();
        if($opt === "value"){
            foreach ((new \DOMXPath($this->doc))->query($query_string) as $item){
                $result[] = $item->textContent;
            }
        }elseif($opt === 'element'){
            foreach ((new \DOMXPath($this->doc))->query($query_string) as $item){
                $result[] = $this->doc->saveHTML($item);
            }
        }else{
            return false;
        }

        return $result;
    }

    /**
     *
     * 连接查询时候的组建query string
     * @param $str
     * @return string
     */
    private function build_query($str){
        $query_string = '';

        if(!empty($str)){
            foreach (explode('>',$str) as $item){
                $item = trim($item);

                if($item[0] =='#'){
                    $query_string .= '//*[@id="'.substr($item,1).'"]';
                }elseif($item[0] == '.'){
                    $query_string .= '//*[@class="'.substr($item,1).'"]';
                }else{
                    $query_string .= "//".$item;
                }
            }
        }

        return $query_string;
    }
}